import {
  WebSocketGateway,
  WebSocketServer,
  SubscribeMessage,
  MessageBody,
  ConnectedSocket,
  OnGatewayConnection,
  OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Logger, UseGuards } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
import { MonitorService } from './monitor.service';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';

@WebSocketGateway({
  cors: {
    origin: process.env.FRONTEND_URL || 'http://localhost:8000',
    credentials: true,
  },
  namespace: '/monitor',
})
export class MonitorGateway implements OnGatewayConnection, OnGatewayDisconnect {
  @WebSocketServer()
  server: Server;

  private readonly logger = new Logger(MonitorGateway.name);
  private connectedClients = new Set<string>();
  private monitoringInterval: NodeJS.Timeout;

  constructor(private readonly monitorService: MonitorService) {}

  afterInit() {
    this.logger.log('WebSocket Gateway initialized');
    this.startMonitoring();
  }

  handleConnection(client: Socket) {
    this.logger.log(`Client connected: ${client.id}`);
    this.connectedClients.add(client.id);
    
    // 发送初始数据
    this.sendInitialData(client);
  }

  handleDisconnect(client: Socket) {
    this.logger.log(`Client disconnected: ${client.id}`);
    this.connectedClients.delete(client.id);
    
    // 如果没有客户端连接，停止监控
    if (this.connectedClients.size === 0) {
      this.stopMonitoring();
    }
  }

  @SubscribeMessage('subscribe-metrics')
  handleSubscribeMetrics(@ConnectedSocket() client: Socket) {
    this.logger.log(`Client ${client.id} subscribed to metrics`);
    client.join('metrics');
    return { status: 'subscribed' };
  }

  @SubscribeMessage('unsubscribe-metrics')
  handleUnsubscribeMetrics(@ConnectedSocket() client: Socket) {
    this.logger.log(`Client ${client.id} unsubscribed from metrics`);
    client.leave('metrics');
    return { status: 'unsubscribed' };
  }

  @SubscribeMessage('get-system-info')
  async handleGetSystemInfo(@ConnectedSocket() client: Socket) {
    try {
      const systemInfo = await this.monitorService.getSystemInfo();
      client.emit('system-info', systemInfo);
    } catch (error) {
      this.logger.error('Failed to get system info', error);
      client.emit('error', { message: 'Failed to get system info' });
    }
  }

  @SubscribeMessage('get-application-metrics')
  async handleGetApplicationMetrics(@ConnectedSocket() client: Socket) {
    try {
      const appMetrics = await this.monitorService.getApplicationMetrics();
      client.emit('application-metrics', appMetrics);
    } catch (error) {
      this.logger.error('Failed to get application metrics', error);
      client.emit('error', { message: 'Failed to get application metrics' });
    }
  }

  @SubscribeMessage('get-metrics-history')
  async handleGetMetricsHistory(
    @ConnectedSocket() client: Socket,
    @MessageBody() data: { duration?: string },
  ) {
    try {
      const history = this.monitorService.getMetricsHistory(data.duration);
      client.emit('metrics-history', history);
    } catch (error) {
      this.logger.error('Failed to get metrics history', error);
      client.emit('error', { message: 'Failed to get metrics history' });
    }
  }

  @SubscribeMessage('get-health-check')
  async handleGetHealthCheck(@ConnectedSocket() client: Socket) {
    try {
      const healthCheck = await this.monitorService.getHealthCheck();
      client.emit('health-check', healthCheck);
    } catch (error) {
      this.logger.error('Failed to get health check', error);
      client.emit('error', { message: 'Failed to get health check' });
    }
  }

  @SubscribeMessage('get-log-analysis')
  async handleGetLogAnalysis(@ConnectedSocket() client: Socket) {
    try {
      const logAnalysis = await this.monitorService.getLogAnalysis();
      client.emit('log-analysis', logAnalysis);
    } catch (error) {
      this.logger.error('Failed to get log analysis', error);
      client.emit('error', { message: 'Failed to get log analysis' });
    }
  }

  private async sendInitialData(client: Socket) {
    try {
      const [systemMetrics, systemInfo, appMetrics, healthCheck] = await Promise.all([
        this.monitorService.getSystemMetrics(),
        this.monitorService.getSystemInfo(),
        this.monitorService.getApplicationMetrics(),
        this.monitorService.getHealthCheck(),
      ]);

      client.emit('initial-data', {
        systemMetrics,
        systemInfo,
        appMetrics,
        healthCheck,
      });
    } catch (error) {
      this.logger.error('Failed to send initial data', error);
      client.emit('error', { message: 'Failed to load initial data' });
    }
  }

  private startMonitoring() {
    if (this.monitoringInterval) {
      return;
    }

    this.logger.log('Starting system monitoring');
    
    this.monitoringInterval = setInterval(async () => {
      if (this.connectedClients.size === 0) {
        return;
      }

      try {
        const [systemMetrics, appMetrics, healthCheck, logAnalysis] = await Promise.all([
          this.monitorService.getSystemMetrics(),
          this.monitorService.getApplicationMetrics(),
          this.monitorService.getHealthCheck(),
          this.monitorService.getLogAnalysis(),
        ]);

        // 广播实时数据到所有订阅的客户端
        this.server.to('metrics').emit('real-time-metrics', {
          systemMetrics,
          appMetrics,
          healthCheck,
          logAnalysis,
          timestamp: Date.now(),
        });

        // 检查是否有告警条件
        await this.checkAlerts(systemMetrics, healthCheck);
        
      } catch (error) {
        this.logger.error('Failed to broadcast monitoring data', error);
      }
    }, 5000); // 每5秒发送一次数据
  }

  private stopMonitoring() {
    if (this.monitoringInterval) {
      this.logger.log('Stopping system monitoring');
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
  }

  private async checkAlerts(systemMetrics: any, healthCheck: any) {
    const alerts = [];

    // CPU 使用率告警
    if (systemMetrics.cpu > 80) {
      alerts.push({
        type: 'warning',
        title: 'CPU 使用率过高',
        message: `当前 CPU 使用率: ${systemMetrics.cpu}%`,
        timestamp: Date.now(),
      });
    }

    // 内存使用率告警
    if (systemMetrics.memory > 85) {
      alerts.push({
        type: 'warning',
        title: '内存使用率过高',
        message: `当前内存使用率: ${systemMetrics.memory}%`,
        timestamp: Date.now(),
      });
    }

    // 磁盘使用率告警
    if (systemMetrics.disk > 90) {
      alerts.push({
        type: 'error',
        title: '磁盘空间不足',
        message: `当前磁盘使用率: ${systemMetrics.disk}%`,
        timestamp: Date.now(),
      });
    }

    // 系统健康状态告警
    if (healthCheck.status === 'unhealthy') {
      alerts.push({
        type: 'error',
        title: '系统健康检查失败',
        message: '系统运行状态异常，请及时处理',
        timestamp: Date.now(),
      });
    }

    // 如果有告警，发送给所有客户端
    if (alerts.length > 0) {
      this.server.emit('system-alerts', alerts);
    }
  }

  // 手动触发告警（用于测试）
  @SubscribeMessage('trigger-test-alert')
  handleTriggerTestAlert() {
    const testAlert = {
      type: 'info',
      title: '测试告警',
      message: '这是一个测试告警消息',
      timestamp: Date.now(),
    };

    this.server.emit('system-alerts', [testAlert]);
    return { status: 'alert-sent' };
  }
}